package org.example.demo;

import java.sql.*;

/**
 * 执行一条已经“解析好”的 SQL（即占位符已被替换，如 #{id} -> -1）
 */
public class ExecuteParsedSql {

    // Kingbase 数据库连接信息
    private static final String DRIVER_CLASS = "com.kingbase8.Driver";
    private static final String JDBC_URL = "jdbc:kingbase8://localhost:54321/testdb"; // 修改为你的地址
    private static final String USERNAME = "system";  // 默认用户
    private static final String PASSWORD = "123456";  // 修改为你的密码

    static {
        try {
            Class.forName(DRIVER_CLASS);
            System.out.println("✅ Kingbase 驱动加载成功: " + DRIVER_CLASS);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException("❌ 找不到 Kingbase JDBC 驱动，请检查 lib 目录是否包含 kingbase8-*.jar", e);
        }
    }

    /**
     * 执行一条已经解析好的 SQL（自动判断是查询还是更新）
     *
     * @param parsedSql 已经替换 #{xxx} 为真实值（如 -1）的 SQL 语句
     */
    public static void execute(String parsedSql) {
        if (parsedSql == null || parsedSql.trim().isEmpty()) {
            System.out.println("⚠️  SQL 为空，不执行。");
            return;
        }

        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;

        try {
            // 建立连接
            conn = DriverManager.getConnection(JDBC_URL, USERNAME, PASSWORD);
            System.out.println("✅ 数据库连接成功");

            // 使用 Statement（因为 SQL 已经是完整字符串，无需预编译）
            stmt = conn.createStatement();

            // 判断是查询还是更新（SELECT / EXPLAIN 等返回结果集）
            boolean isQuery = parsedSql.trim().toUpperCase().startsWith("SELECT") ||
                              parsedSql.trim().toUpperCase().startsWith("EXPLAIN") ||
                              parsedSql.trim().toUpperCase().startsWith("WITH");

            long startTime = System.currentTimeMillis();

            if (isQuery) {
                // 执行查询
                rs = stmt.executeQuery(parsedSql);
                System.out.println("✅ 查询执行成功，耗时: " + (System.currentTimeMillis() - startTime) + "ms");

                // 打印结果
                printResultSet(rs);
            } else {
                // 执行更新（INSERT, UPDATE, DELETE, CREATE, ALTER, DROP 等）
                int affectedRows = stmt.executeUpdate(parsedSql);
                long endTime = System.currentTimeMillis();
                System.out.println("✅ 执行成功，类型: 更新/DDL，影响行数: " + affectedRows + "，耗时: " + (endTime - startTime) + "ms");
            }

        } catch (SQLException e) {
            System.err.println("❌ SQL 执行失败: " + e.getMessage());
            System.err.println("📌 SQL 语句: " + parsedSql);
            e.printStackTrace();
        } finally {
            closeQuietly(rs, stmt, conn);
        }
    }

    /**
     * 打印查询结果集
     */
    private static void printResultSet(ResultSet rs) throws SQLException {
        ResultSetMetaData metaData = rs.getMetaData();
        int columnCount = metaData.getColumnCount();

        // 打印列名
        for (int i = 1; i <= columnCount; i++) {
            System.out.printf("%-20s", metaData.getColumnName(i));
        }
        System.out.println();
        System.out.println("-".repeat(20 * columnCount));

        // 打印数据
        int rowCount = 0;
        while (rs.next() && rowCount < 100) { // 限制最多输出 100 行
            for (int i = 1; i <= columnCount; i++) {
                Object value = rs.getObject(i);
                System.out.printf("%-20s", value == null ? "NULL" : value.toString());
            }
            System.out.println();
            rowCount++;
        }

        if (rowCount == 100) {
            System.out.println("...(仅显示前 100 行)");
        }
        System.out.println("✅ 共显示 " + rowCount + " 行数据。");
    }

    /**
     * 安静关闭资源
     */
    private static void closeQuietly(AutoCloseable... closeables) {
        for (AutoCloseable c : closeables) {
            if (c != null) {
                try {
                    c.close();
                } catch (Exception e) {
                    // 忽略
                }
            }
        }
    }

    // ==================== 测试入口 ====================
    public static void main(String[] args) {
        // 示例 1：查询（来自 MyBatis 模板，已替换 #{id} 为 -1）
        String sql1 = "SELECT * FROM users WHERE id = -1";

        // 示例 2：带 IN 的查询
        String sql2 = "SELECT * FROM users WHERE age IN (-1, -1)";

        // 示例 3：更新语句
        String sql3 = "UPDATE users SET name = 'test' WHERE id = -1";

        // 执行测试
        execute(sql1);
        System.out.println();
        execute(sql2);
        System.out.println();
        execute(sql3);
    }
}